Fork me on GitHub

Jenkins 自动化部署上线

摘要

jenkins 自动化部署项目, 通过 jenkins 部署来节省运维时间, 不需要手动 cp 上线及版本发布

一、Jenkins 是什么

Jenkins 是一款自包含的开源自动化服务, 可用于自动执行与构建, 测试和交付或部署软件有关的各种任务。

Jenkins 目前可以通过本地系统软件包 Docker 进行安装, 甚至可以通过任何安装了 Java 运行环境的计算机独立运行

二、上线流程图

既然我们说到自动化上线, 我们就不得不说说一个项目上线的流程. 只有规范起来才可以做到不出事故!

上线流程图如下图所示

三、Jenkins 安装配置

Jenkins 依赖 Java 环境, 我们需要安装 Java 环境以及相关的环境准备

### 关闭防火墙
$ iptables -F
$ iptables -X
$ systemctl stop firewalld
$ systemctl disable firewalld
### 安装 yum 源
$ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
$ yum clean all && yum makecache   

1. 下载 Jdk 包

下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

上传 jdk 包到服务器

### 解压拷贝 jdk
$ tar xf jdk-8u171-linux-x64.tar.gz -C /usr/local/
$ ln -s /usr/local/jdk1.8.0_171/ /usr/local/jdk
$ ln -s /usr/local/jdk/bin/java /usr/bin/java
### 设置环境变量
$ vim /etc/profile
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
$ source  /etc/profile

2. 安装 Jenkins

$ wget  -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo
$ rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
$ yum install jenkins -y
$ systemctl start jenkins
## 如果我们启动 Jenkins 出现错误可以直接使用 systemctl status jenkins 查看错误

jenkins 相关目录释义:

(1)/usr/lib/jenkins/:jenkins 安装目录,war 包会放在这里。
(2)/etc/sysconfig/jenkins:jenkins 配置文件,“端口”,“JENKINS_HOME”等都可以在这里配置。
(3)/var/lib/jenkins/:默认的 JENKINS_HOME。
(4)/var/log/jenkins/jenkins.log:jenkins 日志文件。

检查端口是否存在

3. 配置 Jenkins

Jenkins 有安全策略, 我们按照提示拷贝验证码即可

将验证码复制到 Web 框里

我们这里使用推荐就可以了,因为后期我们都可以在安装

安装插件中,有的插件会因为网络问题无法安装成功

我们这里可以创建一个管理员,或者直接使用 admin

我们最好不要直接使用admin

安装完成访问地址:iP:8080

到这里我们 Jenkins 已经安装成功, 剩下的就是配置插件和配置环境

因为我们目前什么都没有需要安装插件, 点击下步安装插件

为了模拟环境我们需要安装 Jenkins 一些相关插件

下面 2 个 maven 插件都需要勾选

插件名称:maven lntergration

我们勾选安装重启

安装完成后如下图所示
默认是没有下面的 maven 项目的

4.Jenkins 配置项目

配置 SVN 地址
因为我是新建的 Jenkins 目录, 没有权限, 所以需要创建一个用于认证.

填写 SVN 地址,因为我这里的 svn 已经链接到 ldap, 所以不需要输入 svn 的密码, 默认这里是 svn 的用户和密码

具体文章可以参考 VisualSVN 迁移至 Linux SVN+Apache+ssl 集成 LDAP

认证成功之后

了解 maven 配置
首先我们的 svn 分支下面需要有 pom.xml

继续往下




因为我们只安装 maven 的插件,并没有安装 maven 服务,所以这里需要我们配置

我们就在这里添加一个名字,maven 就自动安装了

Maven 安装完成了,需要依赖吧都是从 maven.apache.org 下载会比较慢,所以我们指定私服的地址, 因为在实际生产中也都是使用私服的。

在 maven 的配置文件里面也需要配置 配置文件 conf/settings.xml 因为我们所使用的是 Jenkins 的自动安装,而不是指定路径所以我们要查到这个配置文件

maven 自动安装的配置路径

配置 Maven 仓库地址

这里配置的都是私服地址

相关文章 Jenkins+Maven+SVN+Nexus 搭建持续集成环境

配置 Maven 镜像地址

配置 Maven 编译参数 [研发都会]

相关文章:maven 编译命令

这个 pom.xml 里面配置是私服的地址

因为代码里面有很多东西是需要拉去依赖包,这些依赖包就存放在本地的私有仓库里(Nexus)

代码中 pom.xml 配置如下
私有仓库的地址

5. 构建测试

控制台输出说明

6.Jenkins 工程目录

可以通过修改 Jenkins 主目录

Jenkins 打包好后的目录,这个 war 包就是我们需要拷贝的 tomcat 下面的

四、Jenkins 自动化部署项目案例

因为目前环境原因,我这里只是截图 Jenkins 发布的流程(本次演示只是针对测试环境日常发布版本)

(1) Java 环境演示 [Jenkins 和 Tomcat 在一台服务器上]

1.Jenkins 配置

SVN 部分配置

maven 及脚本设置

2. 不发脚本配置如下:

相关参考:Jenkins 可用环境变量列表
脚本的存放路径可以在 系统管理 -> 全局配置 ->Jenkins 路径

Last login: Thu Jun 28 18:01:59 2018 from 172.16.29.39
[root@tomcat ~]# cat /jenkins/deploy.sh
#!/bin/bash
#
# Jenkins 工程构建通用 TOMCAT 部署脚本
# @author abcdocker
# @create_time 2017-08-19
#
# 在 Jenkins 内配置部署单元参数
#  参数格式:MAVEN_MODULE_NAME:TOMCAT_ABSOLUTE_PATH  MAVEN 模块名称: 需要部署的目标 TOMCAT 绝对路径
#  只有单个部署单元且没有 Maven 子模块时,模块名称参数可以没有,参数格式为:TOMCAT_ABSOLUTE_PATH
#
# 注意:
#  在本部署脚本内会执行 TOMCAT 启动脚本,为避免 Jenkins 在构建成功以后杀掉所有衍生的后台进程,需要在 Jenkins 内配置全局环境变量 BUILD_ID 值为 allow_to_run_as_daemon
#
#
DEPLOY_TARGET_TOMCAT=$TOMCAT
#校验部署参数,不能为空
if [-z "$DEPLOY_TARGET_TOMCAT"]
then
echo
echo 部署参数为空,部署失败!
echo "#####################################################################"
echo
echo 单个部署单元参数格式:
echo  MAVEN_MODULE_NAME:TOMCAT_ABSOLUTE_PATH MAVEN 模块名称: 需要部署的目标 TOMCAT 绝对路径
echo
echo 多个部署单元参数格式:(多个部署单元使用空格分割)
echo  MAVEN_MODULE_NAME:TOMCAT_ABSOLUTE_PATH MAVEN_MODULE_NAME:TOMCAT_ABSOLUTE_PATH
echo
echo "#####################################################################"
exit 1
fi
echo
echo 部署参数:${DEPLOY_TARGET_TOMCAT}
TOMCAT_ARR=${DEPLOY_TARGET_TOMCAT//;/}
ARR=($TOMCAT_ARR)
ARR_LEN=${#ARR[*]}
echo 共 ${ARR_LEN} 个部署单元
i=1
#获取 Jenkins 传入的目标 TOMCAT 组
for T in $TOMCAT_ARR
do
echo
echo 开始 处理第 ${i} 个部署单元
echo 第一个部署单元:$T
#获取目标 TOMCAT 的 WAR 路径和 TOMCATA 的绝对路径
TOMCAT_PARAM=(${T//:/})
MODULE_NAME=${TOMCAT_PARAM[0]}
TARGET_TOMCAT_PATH=${TOMCAT_PARAM[1]}
WAR_PATH="$WORKSPACE/$MODULE_NAME/target/*.war"
echo 部署单元模块名称:"${MODULE_NAME}"
echo 部署 WAR 包路径:"${WAR_PATH}"
echo 部署 TOMCAT 路径:"${TARGET_TOMCAT_PATH}"
#需要考虑 MAVEN 单模块下的部署问题
#if ["${#ARR[*]}" -eq 1 -a -z "$TARGET_TOMCAT_PATH" ]
if ["$ARR_LEN" -eq 1 -a -z "$TARGET_TOMCAT_PATH"]
then
#MAVEN 过程没有子模块,单个部署单元
TARGET_TOMCAT_PATH=$MODULE_NAME
MODULE_NAME="NULL"
fi
#校验参数,WORKSPACE 变量来自于 Jenkins 环境变量
if [-z "$MODULE_NAME" -o ! -f $WAR_PATH]
then
echo 错误:MAVEN 部署模块名称 参数为空 或 找不到 WAR 包!
echo 部署失败!
exit 1
fi
if [-z "$TARGET_TOMCAT_PATH" -o ! -d "$TARGET_TOMCAT_PATH"]
then
echo 错误:目标 TOMCAT 绝对路径 参数为空 或 该 TOMCAT 目录不存在!
echo 部署失败!
exit 1
fi
echo 开始清理目标 TOMCAT 启动进程...
TOMCAT_PID=`ps -ef |grep "$TARGET_TOMCAT_PATH" |grep  "start" |awk '{print $2}'`
if [-n "$TOMCAT_PID"]
then
echo TOMCAT_${i},PID${TOMCAT_PID},正在结束该进程...
kill -9 $TOMCAT_PID && echo PID${TOMCAT_PID} 已被干掉!
else
echo TOMCAT_${i} 进程未启动!
fi
echo 开始清理目标 TOMCAT 缓存...
rm -rf $TARGET_TOMCAT_PATH/webapps/*
rm -rf $TARGET_TOMCAT_PATH/logs/*
rm -rf $TARGET_TOMCAT_PATH/work/*
echo 开始部署 WAR 包...
cp -a $WAR_PATH $TARGET_TOMCAT_PATH/webapps/ROOT.war && echo WAR 包部署完毕。
echo 开始启动目标 TOMCAT 服务...
sleep 10
/bin/bash $TARGET_TOMCAT_PATH/bin/startup.sh
echo 开始配置 web 目录的 FTP 权限...
#启动过程会自动解压 WAR 包,所以在这里需要等待 WAR 包解压完成再调整目录权限
sleep 30
chown -R vftpuser.vftpuser ${TARGET_TOMCAT_PATH}/webapps/ && echo 目录权限配置完毕。
echo 部署成功
echo 完成 第 ${i} 个部署单元处理。
echo
((i++))
done

3. 构建效果如下图所示

(2) Java 环境演示 [Jenkins 和 Tomcat 不在一台服务器上]

上面的脚本是针对 Jenkins 和 Tomcat 都在相同的目录, 有的时候我们测试环境会存在不在一台服务器的情况, 脚本如下

只是脚本简单的修改

[root@tomcat ~]# cat /jenkins/ysc.sh
#!/bin/bash
#
# Jenkins 工程构建通用 TOMCAT 部署脚本
# @author 刘曙
# @create_time 2017-08-19
#
# 在 Jenkins 内配置部署单元参数
#  参数格式:MAVEN_MODULE_NAME:TOMCAT_ABSOLUTE_PATH  MAVEN 模块名称: 需要部署的目标 TOMCAT 绝对路径
#  只有单个部署单元且没有 Maven 子模块时,模块名称参数可以没有,参数格式为:TOMCAT_ABSOLUTE_PATH
#
# 注意:
#  在本部署脚本内会执行 TOMCAT 启动脚本,为避免 Jenkins 在构建成功以后杀掉所有衍生的后台进程,需要在 Jenkins 内配置全局环境变量 BUILD_ID 值为 allow_to_run_as_daemon
#
#
DEPLOY_TARGET_TOMCAT=$YSC
HOST=root@172.16.1.35
#校验部署参数,不能为空
if [-z "$DEPLOY_TARGET_TOMCAT"]
then
echo
echo 部署参数为空,部署失败!
echo "#####################################################################"
exit 1
fi
echo
echo 部署参数:${DEPLOY_TARGET_TOMCAT}
TOMCAT_ARR=${DEPLOY_TARGET_TOMCAT//;/}
ARR=($TOMCAT_ARR)
ARR_LEN=${#ARR[*]}
echo 共 ${ARR_LEN} 个部署单元
i=1
#获取 Jenkins 传入的目标 TOMCAT 组
for T in $TOMCAT_ARR
do
echo
echo 开始 处理第 ${i} 个部署单元
echo 第一个部署单元:$T
#获取目标 TOMCAT 的 WAR 路径和 TOMCATA 的绝对路径
TOMCAT_PARAM=(${T//:/})
MODULE_NAME=${TOMCAT_PARAM[0]}
TARGET_TOMCAT_PATH=${TOMCAT_PARAM[1]}
#WAR_PATH="/jenkins/workspace/ysc-all/${MODULE_NAME}/target/*.war"
WAR_PATH="${WORKSPACE}/${MODULE_NAME}/target/*.war"
echo 部署单元模块名称:"${MODULE_NAME}"
echo 部署 WAR 包路径:"${WAR_PATH}"
echo 部署 TOMCAT 路径:"${TARGET_TOMCAT_PATH}"
#判断 IP 是否有相关目录
ssh 172.16.1.35 "[-d $TARGET_TOMCAT_PATH]" >/dev/null 2>&1
if [$? != 0];then
   echo 错误
else
   echo  正确
fi
#校验参数,WORKSPACE 变量来自于 Jenkins 环境变量
if [-z "$MODULE_NAME" -o ! -f $WAR_PATH]
then
echo 错误:MAVEN 部署模块名称 参数为空 或 找不到 WAR 包!
echo 部署失败!
exit 1
fi
#scp 软件包
   ssh $HOST /etc/init.d/${MODULE_NAME} stop
   ssh 172.16.1.35 "[-d $TARGET_TOMCAT_PATH/webapps/ROOT/]" >/dev/null 2>&1
   if [$? = 0];then
  ssh 172.16.1.35 rm -rf $TARGET_TOMCAT_PATH/webapps/ROOT
if [$? = 0];then
   scp  $WAR_PATH root@172.16.1.35:$TARGET_TOMCAT_PATH/webapps/ROOT.war && echo WAR 包部署完毕。
   echo $TARGET_TOMCAT_PATH is OK
else
   echo 删除 $TARGET_TOMCAT_PATH is error
fi
   else
   echo "not found $TARGET_TOMCAT_PATH/webapps/ROOT"
   scp  $WAR_PATH root@172.16.1.35:$TARGET_TOMCAT_PATH/webapps/ROOT.war && echo WAR 包部署完毕。
   ssh $HOST /etc/init.d/${MODULE_NAME} restart
   fi
#################### 启动文件
done
  #scp /home/config.properties/ysc/${MODULE_NAME}.js root@172.16.1.35:$TARGET_TOMCAT_PATH/webapps/ROOT/web/js/basePath.js
  ssh $HOST /etc/init.d/${MODULE_NAME} restart

Jenkins 配置如下修改

修改完成后我们构建演示

提示:这种环境下配置文件都是通过 maven build 进行控制,也就是通过研发控制配置文件

  • +

(3) Java 环境演示 [上线脚本]

线上环境演示
我们的上线流程如下:

Jenkins 配置如下

  • 1. 首先测试环境脚本:

    [root@tomcat ~]# cat /server/scripts/.upgrade-smscenter.sh
    #!/bin/bash
    WAR=”/jenkins/workspace/portal-smscenter/bxg-sms-center-web/target/*.war”
    Path=”/data/hub/bxg-smscenter/date +%Y%m%d/“
    scp_war(){
    if [! -d $Path];then

    ssh root@file-server mkdir -p $Path
    

    scp $WAR root@file-server:$Path
    else
    scp $WAR root@file-server:$Path
    fi
    }
    ssh_file(){

    ssh root@file-server "/bin/bash /server/script/bxg/bxg-smscenter.sh"
    

    }
    scp_war
    ssh_file

2. 跳板机脚本修改

[root@File-server1 ~]# cat /server/script/bxg/bxg-smscenter.sh
#!/bin/bash
HOST=online-server2
WAR="/data/hub/bxg-smscenter/`date +%Y%m%d`"
DIR="/application/smscenter/webapps/ROOT/"
function scp_file {if `ssh root@$HOST "[ ! -d $WAR]"`;then
ssh root@$HOST "mkdir -p $WAR"
fi
scp $WAR/*.war root@$HOST:$WAR/
echo "scp $WAR/*.war root@$HOST:$WAR/"
}
ssh_deploy(){ssh root@$HOST "/bin/bash /server/scripts/deploy_smscenter.sh"}
scp_file
ssh_deploy

3.web 服务器脚本

[root@online-server2 ~]# cat /server/scripts/deploy_smscenter.sh
#!/bin/bash
WAR="/data/hub/bxg-smscenter/`date +%Y%m%d`"
OBJECT="/application/smscenter/webapps/ROOT/"
Backup="/data/tomcat/bxg-smscenter-`date +%Y%m%d`"
SCR_D="/application/smscenter/webapps/ROOT"
#config="/data/bak"
backup_tar(){
tar zcvf $Backup.tar.gz $SCR_D/
echo " 为了防止意外 cp 整个项目目录存放 "
cp -a $SCR_D/ $Backup
rm -rf $OBJECT/*
}
cp_war(){unzip $WAR/*.war -d $SCR_D/}
cp_config(){
cat $Backup/WEB-INF/classes/application-prod.properties >$SCR_D/WEB-INF/classes/application-prod.properties
/etc/init.d/smscenter restart
}
backup_tar
cp_war
cp_config
[root@online-server2 ~]#

相关文章 企业必会技能 tomcat

  • +

(4) NodeJs 环境演示 [上线脚本]

node 环境上线流程
Jenkins 配置如下 [node 项目不适用 maven, 所以可以不用创建 maven 项目, 直接在 Jenkins 创建普通项目就可以]

1. 测试环境脚本

[root@tomcat ~]# cat /server/scripts/mobile/mobile.sh
#!/bin/bash
source /etc/profile
HOST=file-server
BASE_DIR=/server/scripts/mobile/m
url=$1
server=$2
DATE=`date +%Y%m%d`
tar(){
rm -rf $BASE_DIR
[-d $BASE_DIR] || mkdir $BASE_DIR
cd $BASE_DIR
    echo "##########################################################"
    echo " 代码拉取中!!!"
    svn co -q $url/ .
echo "##########################################################"
}
cp(){cd ${BASE_DIR}
    /bin/tar -zcvf m_${DATE}.tar.gz ./*
echo "##########################################################"
echo " 文件已经打包完成! 正在拷贝中!!!"
echo "##########################################################"
sleep 5
scp  m_${DATE}.tar.gz root@$HOST:/data/hub/bxg-mobile/
echo "##########################################################"
echo " 文件已经拷贝完成! 正在上传服务器中!!!"
echo "##########################################################"
ssh root@file-server "/bin/bash /server/script/bxg/bxg-mobile.sh $server"
}
tar
cp
[root@tomcat ~]#

2. 跳板机脚本

[root@File-server1 ~]# cat /server/script/bxg/bxg-mobile.sh
#!/bin/bash
HOST=$1
Mobile_tar="/data/hub/bxg-mobile"
DIR="/application/node"
DATE=`date +%Y%m%d`
scp_file(){if `ssh root@$HOST "[ ! -d $Mobile_tar]"`;then
ssh root@$HOST "mkdir -p $Mobile_tar"
fi
scp $Mobile_tar/m_${DATE}.tar.gz root@$HOST:$DIR/
sleep 3
echo "   "
echo "##########################################################"
echo "File-server 正在拷贝 ${HOST}!!!"
sleep 3
echo "##########################################################"
}
ssh_deploy(){
   echo "Hi"
ssh root@$HOST "/bin/bash /server/scripts/bxg/bxg-mobile.sh"
}
scp_file
ssh_deploy

3.web 发布脚本

[root@iZbp11tefvghtcfn5mudgdZ ~]# cat /server/scripts/bxg/bxg-mobile.sh
#!/bin/bash
source /etc/profile
DIR="/application/node"
DATE=`date +%Y%m%d`
Backup="/application/node/m/"
BAK="/data/hub/bxg-mobile"
backup_tar(){
echo " 为了防止意外 cp 整个项目目录存放 "
cp -ar $Backup ${BAK}/mobile_$DATE
echo "online-server 原目录拷贝备份完成!"
}
cp_war(){
/etc/init.d/mobile stop
#mv $Backup /tmp/m_${DATE} && rm -rf /tmp/m_${DATE}
    rm -rf $Backup
mkdir $Backup && cd /application/node/
    tar xf m_${DATE}.tar.gz -C $Backup
}
npm_config(){
cd $Backup
    cnpm install
    npm run build-prod
    npm run start-prod &>/var/log/mobile_${DATE}.log &
}
C(){
echo "++++++++++++++++++++++++++++++++++++++++++++++++++++"
curl  -I 127.0.0.1:3000
echo "###################################################"
echo " 若是 200 服务启动正常! 可以启动另一台!"
echo "###################################################"
}
backup_tar
cp_war
npm_config
C

总结:Jenkins 自动化不是运维一个人就可以完成的, 需要研发的参与, 本文只是给大家展示一下我公司的自动化, 我眼里所谓的自动化. 希望大家不喜勿喷, 对文章有意见或建议请在评论留言哦~

转自:Jenkins 自动化部署上线

赞赏是最好的支持与鼓励!
-------------本文结束感谢您的阅读-------------